﻿using ABB.Robotics.Controllers.Configuration;
using ABB.Robotics.Controllers.Discovery;
using ABB.Robotics.Controllers;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ABB.Robotics.Controllers.RapidDomain;
using System.Diagnostics;
using System.Windows;
using System.IO;
using Deepseek_Robot.Modules.Utils;
using static RobotStudio.Services.RobApi.Transport.RWS.RobFileTransferLegacyRWS;
using RobotStudio.Services.RobApi.Transport.RobAPI1Direct;
using Task = System.Threading.Tasks.Task;
using Microsoft.Win32;
using RobotStudio.Services.RobApi.Interop;
using System.Windows.Input;
using System.Windows.Threading;
using ClosedXML.Excel;

using CommunityToolkit.Mvvm.ComponentModel;
using System.Windows.Controls;
using System.Text.RegularExpressions;
using ABB.Robotics.Controllers.MotionDomain; // 用于解析 Excel 文件
using RobotStudio;
using ABB.Robotics.RobotStudio.Stations;
using ABB.Robotics.RobotStudio.Environment;
using ABB.Robotics.RobotStudio;
using System.Windows.Automation;
using CommunityToolkit.Mvvm.Messaging;
using Deepseek_Robot.Modules.Models;

namespace Deepseek_Robot.Modules.ViewModels
{
    public partial class AIControlViewModel : ViewModelBase
    {
        public AIControlViewModel()
        {
            // 订阅日志消息事件
            MessageLogTarget.LogMessageReceived += OnLogMessageReceived;

            InitializeAsync();

          
        }



        private void OnLogMessageReceived(string logMessage)
        {
            // 在 UI 线程中更新 MessageLog
            System.Windows.Application.Current.Dispatcher.Invoke(() =>
            {
                if(MessageLog.Length>200)
                {
                    MessageLog = "";
                }
                MessageLog += logMessage + Environment.NewLine;

                
            });
        }

        DoubaoAPI doubaoAPI = new DoubaoAPI();

        #region 属性
        [ObservableProperty]
        [NotifyCanExecuteChangedFor(nameof(UpLoadModuleCommand))]
        private bool _isUpLoadModuleEnabled = true;
        [ObservableProperty]
        private bool _isGenerateModuleEnabled = true;
        [ObservableProperty]
        private bool _isProcessBarVisibility = true;
        [ObservableProperty]
        private string _promptInput = "";
        [ObservableProperty]
        private string _promptInputPreview = "";
        [ObservableProperty]
        private string _moduleName = "";
 
        string ModuleFileName => ModuleName + ".mod";
        [ObservableProperty]
        private string _promptResult = "";
        [ObservableProperty]
        private string _processingInfo = "";
        [ObservableProperty]
        private string _messageLog = "";
        [ObservableProperty]
        private double _progressBarValue = 0;
        [ObservableProperty]
        private bool _isConnect = false;

        private TaskStatusEnum _taskStatus;
        public TaskStatusEnum TaskStatus
        {
            get { return _taskStatus; }
            set
            {
                //if (_taskStatus != value)
                {
                    _taskStatus = value;
                    IsUpLoadModuleEnabled = value is not TaskStatusEnum.Running;
                    IsGenerateModuleEnabled = value is not TaskStatusEnum.Running;
                    // 使用 switch 表达式设置 ProcessingInfo
                    ProcessingInfo = value switch
                    {
                        TaskStatusEnum.Running => "Loading",
                        TaskStatusEnum.Success => "Success",
                        TaskStatusEnum.Failed => "Failed",
                        _ => "Unknown"
                    };
                    OnPropertyChanged(nameof(TaskStatus));
                }
            }
        }
     
        #endregion
        private NetworkScanner scanner { get; set; } = new();
        private Controller controller;

        public async Task InitializeAsync()
        {
            try
            {
                NLogHelper.Instance.Info("连接ABB机器人");
                IsConnect = await ConnectRobot();
                if (!IsConnect)
                {
                    NLogHelper.Instance.Info("连接ABB机器人:Fail");
                    return;
                }
                var reee = controller.IsMaster;
                NLogHelper.Instance.Info("连接ABB机器人:Success");
                using (Mastership.Request(controller))
                {
                    NLogHelper.Instance.Info("GetTask T_ROB1");
                    var task = controller.Rapid.GetTask("T_ROB1");
                    var modules = task.GetModules();
                    Module module = modules.Where(u => u.Name.ToLower() != "user" && u.Name.ToLower() != "base").First();
                    ModuleName = module.Name;
                    NLogHelper.Instance.Info($"开始获取:{ModuleFileName}");
                    ProcessModule mainModule = Process.GetCurrentProcess().MainModule;
                    if (mainModule == null)
                    {
                        NLogHelper.Instance.Info($"Module is null");
                        return;
                    }
                    NLogHelper.Instance.Info($"Get {ModuleName} 成功");
                    //string moduleDirectory = Path.GetDirectoryName(mainModule.FileName);
                    string moduleDirectory = @"D:\\";
                    string modFilePath = Path.Combine(moduleDirectory, ModuleFileName);
                    string localDir = controller.FileSystem.LocalDirectory;   //获取机器人的home路径
                    string remoteDir = controller.FileSystem.RemoteDirectory;   //获取机器人的home路径

                    NLogHelper.Instance.Info($"Name {module.Name} IsReadOnly:{module.IsReadOnly} Type:{module.Type.ToString()}");
                    
                    NLogHelper.Instance.Info($"SaveToFile {moduleDirectory}");
                    if (controller.IsVirtual)
                    {
                        module.SaveToFile(moduleDirectory); 
                    }
                    else
                    {
                        controller.FileSystem.GetFile(ModuleFileName, modFilePath, true);
                    }
  
                    NLogHelper.Instance.Info($"SaveToFile Done");
                    //controller.FileSystem.GetFile(ModuleFileName, modFilePath, true);  //把Module1保存到PC的debug文件夹中
                    NLogHelper.Instance.Info($"ReadAllText");
                    PromptInputPreview = File.ReadAllText(modFilePath, Encoding.Default);  //读取Module1文件
                    NLogHelper.Instance.Info($"读取程序完成");
                }
            }
            catch (Exception ex)
            {
                NLogHelper.Instance.Info($"{ex.Message}");
                controller?.Dispose();
            }
            finally
            {
                ProcessingInfo = "Done";
                //await DisConnectRobot(); 
            }
        }
        public async Task<bool> ConnectRobot()
        {
            try
            {
                TaskStatus = TaskStatusEnum.Running;
                IsConnect = false;
                if (scanner == null)
                {
                    scanner = new NetworkScanner();
                }
                // 异步扫描网络
                await System.Threading.Tasks.Task.Run(() => scanner.Scan());

                ControllerInfoCollection controllerInfoCollection = scanner.Controllers;
                if (controllerInfoCollection.Count > 0)
                {
                    foreach (ControllerInfo controllerInfo in controllerInfoCollection)
                    {
                        //if(!controllerInfo.IsVirtual)
                        {
                            controller = Controller.Connect(controllerInfo.SystemId, ConnectionType.Standalone);
                            controller.Logon(UserInfo.DefaultUser);
                            IsUpLoadModuleEnabled = true;
                            IsConnect = true;
                            break;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                NLogHelper.Instance.Info($"连接过程中出现错误: {ex.Message}");
            }
            finally
            {
                TaskStatus = IsConnect ? TaskStatusEnum.Success : TaskStatusEnum.Failed;
            }
            return IsConnect;
        }

        public async Task<bool> DisConnectRobot()
        {
            try
            {
                if (controller is null)
                {
                    return true;
                }
                controller.Logoff();   //注销当前用户。
                controller.Dispose();
                controller = null;
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"连接过程中出现错误: {ex.Message}");
                return false;
            }
        }

        public async Task GetPromptResultAsync(string input)
        {
            try
            {
                PromptResult = "";
                await Task.Run(async () =>
                {
                    await foreach (var chunk in doubaoAPI.CallApi(input))
                    {
                        await Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
                        {
                            PromptResult += chunk;
                        }));
                    }
                });
            }
            catch (Exception ex)
            {
                // 处理异常，例如记录日志或显示错误信息
                await Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
                {
                    PromptResult = $"";
                    NLogHelper.Instance.Info($"调用 API 时发生错误: {ex.Message}");
                }));
            }
        }

        [RelayCommand]
        private void LoadParameter()
        {
            // 创建一个 OpenFileDialog 实例
            OpenFileDialog openFileDialog = new OpenFileDialog();

            // 设置文件筛选器，只允许选择 txt 或 mod 文件
            openFileDialog.Filter = "文本文件 (*.txt)|*.txt|模块文件 (*.mod)|*.mod";

            // 显示文件选择对话框
            if (openFileDialog.ShowDialog() == true)
            {
                try
                {
                    // 获取用户选择的文件路径
                    string filePath = openFileDialog.FileName;

                    // 读取文件内容到一个字符串中
                    string fileContent = File.ReadAllText(filePath);

                    // 这里可以将 fileContent 赋值给你需要的属性或进行其他处理
                    PromptInputPreview = MergeConstants(fileContent, PromptInputPreview);

                    // 打印文件内容（仅用于调试）
                    System.Diagnostics.Debug.WriteLine(fileContent);
                }
                catch (IOException ex)
                {
                    // 处理文件读取异常
                 
                }
            }
        }
        public static string MergeConstants(string parameter, string promptInputPreview)
        {
            // 定义正则表达式来匹配 const 常量，不区分大小写
            string constPattern = @"const\s+[^\s]+\s+[^\s]+\s*=\s*[^;]+;";
            Regex regex = new Regex(constPattern, RegexOptions.IgnoreCase);

            // 从 parameter 中提取 const 常量
            MatchCollection parameterMatches = regex.Matches(parameter);
            Dictionary<string, string> parameterConstants = new Dictionary<string, string>();
            foreach (Match match in parameterMatches)
            {
                string constant = match.Value;
                // 提取 CONST 和 := 之间的常量名称
                int startIndex = constant.IndexOf(" ", constant.IndexOf("const", StringComparison.OrdinalIgnoreCase) + 5) + 1;
                int endIndex = constant.IndexOf(":=", startIndex);
                if (startIndex >= 0 && endIndex >= 0)
                {
                    string constantName = constant.Substring(startIndex, endIndex - startIndex).Trim();
                    parameterConstants[constantName] = constant;
                }
            }

            // 从 PromptInputPreview 中提取 const 常量
            MatchCollection previewMatches = regex.Matches(promptInputPreview);
            Dictionary<string, string> previewConstants = new Dictionary<string, string>();
            foreach (Match match in previewMatches)
            {
                string constant = match.Value;
                // 提取 CONST 和 := 之间的常量名称
                int startIndex = constant.IndexOf(" ", constant.IndexOf("const", StringComparison.OrdinalIgnoreCase) + 5) + 1;
                int endIndex = constant.IndexOf(":=", startIndex);
                if (startIndex >= 0 && endIndex >= 0)
                {
                    string constantName = constant.Substring(startIndex, endIndex - startIndex).Trim();
                    previewConstants[constantName] = constant;
                }
            }

            // 检查是否有重复的常量
            bool hasDuplicates = false;
            foreach (var key in parameterConstants.Keys)
            {
                if (previewConstants.ContainsKey(key))
                {
                    hasDuplicates = true;
                    break;
                }
            }

            // 如果有重复的常量，弹出提示框询问用户是否确定合并
            if (hasDuplicates)
            {
                MessageBoxResult result = MessageBox.Show("存在重复的常量，是否确定合并？", "确认合并", MessageBoxButton.YesNo, MessageBoxImage.Question);

                if (result == MessageBoxResult.No)
                {
                    return promptInputPreview; // 用户选择取消，返回原始的 PromptInputPreview
                }
            }

            // 合并常量，若有重复以 parameter 中的为准
            foreach (var kvp in parameterConstants)
            {
                previewConstants[kvp.Key] = kvp.Value;
            }


            // 找到 PromptInputPreview 中第一个 const 行的位置
            Match firstConstMatch = regex.Match(promptInputPreview);
            int insertIndex = firstConstMatch.Success ? firstConstMatch.Index : 0;

            // 移除 PromptInputPreview 中原有的 const 常量部分
            string newPromptInputPreview = regex.Replace(promptInputPreview, "");

            // 删除空行
            newPromptInputPreview = Regex.Replace(newPromptInputPreview, @"^\s*$\n|\r", "", RegexOptions.Multiline);

            // 将合并后的常量添加到 PromptInputPreview 合适的位置
            string combinedConstants = "";
            foreach (var constant in previewConstants.Values)
            {
                combinedConstants += constant + Environment.NewLine;
            }
            newPromptInputPreview = newPromptInputPreview.Insert(insertIndex, combinedConstants);


            return newPromptInputPreview;
        }

        [RelayCommand]
        private async Task RefreshReadModuleAsync()
        {
            await InitializeAsync();
        }


        [RelayCommand]
        private async Task GenerateModuleAsync()
        {
            try
            {
                TaskStatus = TaskStatusEnum.Running;
                await GetPromptResultAsync($"Module的名称是{ModuleFileName}, PROC名称是main(),需要修改的内容是:{PromptInput},以以下代码[ {PromptInputPreview} ]作为基础,你自己不要额外添加注释");
                PromptResult = CleanPromptResult(PromptResult);
                NLogHelper.Instance.Info($"生成程序成功");
                IsGenerateModuleEnabled = true;
                TaskStatus = TaskStatusEnum.Success;
            }
            catch (Exception uploadEx)
            {
                await DisConnectRobot();
                TaskStatus = TaskStatusEnum.Failed;
                NLogHelper.Instance.Error($"生成时出错: {uploadEx.Message} ");
            }
            finally
            {
                await DisConnectRobot();
            }
        }

        private string CleanPromptResult(string result)
        {
            result = result.Replace("```", "").Replace("python", "");
            int startIndex = result.IndexOf("MODULE");
            int endIndex = result.LastIndexOf("ENDMODULE");
            if (startIndex > -1 && endIndex > -1 && endIndex > startIndex)
            {
                endIndex += 9;
                result = result.Substring(startIndex, endIndex - startIndex);
            }
            return result;
        }

        private bool CanUpLoadModule() => IsUpLoadModuleEnabled;

        [RelayCommand(CanExecute = nameof(CanUpLoadModule))]
        private async Task UpLoadModuleAsync()
        {
            TaskStatus = TaskStatusEnum.Running;
            await ConnectRobot();
            ProcessModule mainModule = Process.GetCurrentProcess().MainModule;
            string moduleDirectory = Path.GetDirectoryName(mainModule.FileName);
            string modFilePath = Path.Combine(moduleDirectory, ModuleFileName);
            File.WriteAllText(ModuleFileName, PromptResult);
            using (Mastership.Request(controller))
            {
                try
                {
                    var task = controller.Rapid.GetTask("T_ROB1");
                    NLogHelper.Instance.Info($"连接T_ROB1成功");
                    bool re = false;
                    // 获取 RAPID 任务
                    Module module = task.GetModule(ModuleName);
                    NLogHelper.Instance.Info($"Get{ModuleName}成功");
                    controller.FileSystem.PutFile(modFilePath, ModuleFileName, true);
                    //var GetRapidDatas = task.GetRapidData();
                    var Result = task.GetRobTarget();
                    re = task.LoadModuleFromFile(ModuleFileName, RapidLoadMode.Replace);
                    if (re)
                    {
                        NLogHelper.Instance.Info($"上传{ModuleFileName}成功");
                        NLogHelper.Instance.Info($"开始读取最新程序");
                        controller.FileSystem.GetFile(ModuleFileName, modFilePath, true);
                        NLogHelper.Instance.Info($"读取最新程序成功");
                        PromptInputPreview = File.ReadAllText(modFilePath, Encoding.Default);  //读取Module1文件
                        TaskStatus = TaskStatusEnum.Success;
                    }
                    else
                    {
                        NLogHelper.Instance.Info($"上传{ModuleFileName}失败");
                        TaskStatus = TaskStatusEnum.Failed;
                    }
                }
                catch (Exception uploadEx)
                {
                    NLogHelper.Instance.Info($"上传 .mod 文件时出错: {uploadEx.Message}");
                }
                finally
                {
                    await DisConnectRobot();
                }
            }
        }

        // 处理文件拖放的方法
        public async Task HandleFileDrop(string[] filePaths)
        {
            foreach (var filePath in filePaths)
            {
                if (Path.GetExtension(filePath).Equals(".xlsx", StringComparison.OrdinalIgnoreCase))
                {
                    try
                    {
                        using (var workbook = new XLWorkbook(filePath))
                        {
                            var worksheet = workbook.Worksheet(1);
                            var rows = worksheet.RowsUsed();
                            StringBuilder sb = new StringBuilder();
                            foreach (var row in rows)
                            {
                                foreach (var cell in row.Cells())
                                {
                                    sb.Append(cell.Value.ToString());
                                    sb.Append(" ");
                                }
                                sb.AppendLine();
                            }
                            PromptInput += sb.ToString();
                        }
                    }
                    catch (Exception ex)
                    {
                        NLogHelper.Instance.Info($"解析 Excel 文件时出错: {ex.Message}");
                    }
                }
            }
        }

        [RelayCommand]
        private async Task<bool> RunTaskAndRecord()
        {
            await DisConnectRobot();
            try
            {
                if (EnableCaptureSimulation() is true)
                {
      
                        // 发送页面跳转消息给 MainWindowViewModel
                        WeakReferenceMessenger.Default.Send(new NavigatePageMessage("运动路径"));
                    return true;
                }

            }
            catch (Exception ex)
            {
                return false;
            }
            finally
            {
                
            }
            return false;
        }
        private bool EnableCaptureSimulation()
        {

            Process[] processes = Process.GetProcessesByName("RobotStudio");
            if (processes.Length > 0)
            {
                AutomationElement mainWindow = AutomationElement.FromHandle(processes[0].MainWindowHandle);
                if (mainWindow != null)
                {
                    // 查找仿真录像按钮
                    System.Windows.Automation.Condition condition = new PropertyCondition(AutomationElement.NameProperty, "CmdBarCtl_FileCaptureSimulation");
                    AutomationElement recordButton = mainWindow.FindFirst(TreeScope.Descendants, condition);
                    if (recordButton != null)
                    {
                        // 模拟点击按钮
                        InvokePattern invokePattern = recordButton.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
                        if (invokePattern != null)
                        {
                            invokePattern.Invoke();
                            NLogHelper.Instance.Info($"已点击仿真录像按钮");
                            Thread.Sleep(1000);

                            // 查找播放按钮
                            //Name	CmdBarCtl_SimulationPlay
                            System.Windows.Automation.Condition condition2 = new PropertyCondition(AutomationElement.NameProperty, "CmdBarCtl_SimulationPlay");
                            AutomationElement recordButton2 = mainWindow.FindFirst(TreeScope.Descendants, condition2);
                            if (recordButton2 != null)
                            {
                                // 模拟点击按钮
                                InvokePattern invokePattern2 = recordButton2.GetCurrentPattern(InvokePattern.Pattern) as InvokePattern;
                                if (invokePattern2 != null)
                                {
                                    invokePattern2.Invoke();
                                    NLogHelper.Instance.Info($"已点击播放录像按钮");
                                    Thread.Sleep(4000);
                                    return true;
                                }
                            }
                        }
                    }
                    else
                    {
                        return false ;
                    }
                }
            }
            return false;
     
        }

     


    }
}